#include "PermissionBitsChoseMenu.h"
#include "ui_PermissionBitsChoseMenu.h"

PermissionBitsChoseMenu::PermissionBitsChoseMenu(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::PermissionBitsChoseMenu)
{
    PermissionBitsChoseMenu::initMenu();

    // setWindowIcon(QIcon(":/image/CMSISIcom.svg"));
}

PermissionBitsChoseMenu::PermissionBitsChoseMenu(Role role, PB_t permissionBit, QWidget* parent)
    :QDialog(parent),ui(new Ui::PermissionBitsChoseMenu),
    m_currentPBits(permissionBit)
{
    PermissionBitsChoseMenu::initMenu();
    m_currentRole = role;
    m_currentPBits = permissionBit;
    setWindowTitle(QString(reRoleMap[role]+"权限位页面"));
    ui->stackedWidget->setCurrentIndex(static_cast<int>(role) - 1);//设置当前页面

    PermissionBitsChoseMenu::initCheckBox();
}

PermissionBitsChoseMenu::~PermissionBitsChoseMenu()
{
    delete ui;
}

void PermissionBitsChoseMenu::initMenu()
{
    ui->setupUi(this);

    setWindowIcon(QIcon(":/image/CMSISIcom.svg"));

    connect(ui->btn_cancel,&QPushButton::clicked,this,&QDialog::close);
    connect(ui->btn_affirm,&QPushButton::clicked,this,[this](){emit dataConfirmed(m_currentPBits);QDialog::close();});

    PermissionBitsChoseMenu::initPermissionMappings();
}

void PermissionBitsChoseMenu::initPermissionMappings()
{
    // ===================== 管理员权限 =====================
    m_checkBoxMap.insert(Role::ADMIN,
    {
        {ui->cb_user_add,       UPBits::USER_ADMIN_ADD},
        {ui->cb_user_delete,     UPBits::USER_ADMIN_DELETE},
        {ui->cb_user_update,     UPBits::USER_ADMIN_MODIFY},
        {ui->cb_user_find,       UPBits::USER_ADMIN_FIND},
        {ui->cb_user_show,       UPBits::USER_ADMIN_SHOW},
        {ui->cb_user_lookLog,    UPBits::USER_ADMIN_LOG},
        {ui->cb_user_all,        UPBits::USER_ADMIN_ALL}
    });

    // ===================== 配件录入人员权限 =====================
    m_checkBoxMap.insert(Role::USER_INFO,
    {
        {ui->cb_userInfo_add,         UPBits::USER_INFO_ADD},
        {ui->cb_userInfo_delete,      UPBits::USER_INFO_DELETE},
        {ui->cb_userInfo_update,      UPBits::USER_INFO_MODIFY},
        {ui->cb_userInfo_find,        UPBits::USER_INFO_FIND},
        {ui->cb_userInfo_show,        UPBits::USER_INFO_SHOW},
        {ui->cb_userInfo_allocation,  UPBits::USER_INFO_ASSIGNING},
        {ui->cb_userInfo_all,         UPBits::USER_INFO_ALL}
    });

    // ===================== 仓库管理人员权限 =====================
    m_checkBoxMap.insert(Role::USER_STORE_IO,
    {
        // 入库权限
        {ui->cb_userIO_addIn,      UPBits::USER_SIO_IN_ADD},
        {ui->cb_userIO_deleteIn,   UPBits::USER_SIO_IN_DELETE},
        {ui->cb_userIO_updateIn,   UPBits::USER_SIO_IN_MODIFY},
        {ui->cb_userIO_findIn,     UPBits::USER_SIO_IN_FIND},
        {ui->cb_userIO_showIn,     UPBits::USER_SIO_IN_SHOW},
        {ui->cb_userIO_allIn,      UPBits::USER_SIO_IN_ALL},

        // 出库权限
        {ui->cb_userIO_addOut,     UPBits::USER_SIO_OUT_ADD},
        {ui->cb_userIO_deleteOut,  UPBits::USER_SIO_OUT_DELETE},
        {ui->cb_userIO_updateOut,  UPBits::USER_SIO_OUT_MODIFY},
        {ui->cb_userIO_findOut,    UPBits::USER_SIO_OUT_FIND},
        {ui->cb_userIO_showOut,    UPBits::USER_SIO_OUT_SHOW},
        {ui->cb_userIO_allOut,     UPBits::USER_SIO_OUT_ALL},

        // 操作权限
        {ui->cb_userIO_inStore,    UPBits::USER_SIO_OPERATION_IN},
        {ui->cb_userIO_outStore,   UPBits::USER_SIO_OPERATION_OUT},
        {ui->cb_userIO_all,        UPBits::USER_SIO_ALL}
    });

    // ===================== 仓库盘点人员权限 =====================
    m_checkBoxMap.insert(Role::USER_STORE_CHECK,
    {
        {ui->cb_userCheck_check,        UPBits::USER_SCK_START_CHECK},
        {ui->cb_userCheck_showCurrent,   UPBits::USER_SCK_SHOW_CHECK},
        {ui->cb_userCheck_showHistory,   UPBits::USER_SCK_SHOW_HISCHECK},
        {ui->cb_userCheck_affirm,        UPBits::USER_SCK_AFFRIM},
        {ui->cb_userCheck_all,           UPBits::USER_SCK_ALL}
    });

    //反映射
    //QHash<Role,QHash<QCheckBox*,UPBits>>::iterator
    for(auto roleIt = m_checkBoxMap.begin(); roleIt!=m_checkBoxMap.end();++roleIt)
    {
        Role tmpRole = roleIt.key();
        for(auto checkboxIt = roleIt.value().begin();checkboxIt!=roleIt.value().end();++checkboxIt)
        {
            m_reCheckBoxMap[tmpRole].insert(checkboxIt.value(),checkboxIt.key());
        }
    }

#if MAP_DEBUG
    for(auto roleIt = m_checkBoxMap.begin();roleIt!=m_checkBoxMap.end();++roleIt)
    {
        qDebug() << reRoleMap[roleIt.key()];
        for(auto cbIt = roleIt.value().begin();cbIt!=roleIt.value().end();++cbIt)
        {
            qDebug() << cbIt.key()->objectName() << ":" << static_cast<uint16_t>(cbIt.value());
        }
    }
    qDebug() << "=============================";
    for(auto roleIt = m_reCheckBoxMap.begin();roleIt!=m_reCheckBoxMap.end();++roleIt)
    {
        qDebug() << reRoleMap[roleIt.key()];
        for(auto UPBIt = roleIt.value().begin();UPBIt!=roleIt.value().end();++UPBIt)
        {
            qDebug() << static_cast<uint16_t>(UPBIt.key()) << ":" << UPBIt.value()->objectName();
        }
    }
#endif

    //=====各个角色ALL权限的逻辑=====
    connect(ui->cb_user_all,&QCheckBox::stateChanged,this,[this](int state)
            {
                for(auto cbIt : m_reCheckBoxMap[Role::ADMIN])
                {
                    if(cbIt == ui->cb_user_all)
                        continue;
                    cbIt->blockSignals(true);
                    if(state == Qt::Unchecked)
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));
                    else
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                    cbIt->blockSignals(false);
                }
            });
    connect(ui->cb_userInfo_all,&QCheckBox::stateChanged,this,[this](int state)
            {
                for(auto cbIt : m_reCheckBoxMap[Role::USER_INFO])
                {
                    if(cbIt == ui->cb_userInfo_all)
                        continue;
                    cbIt->blockSignals(true);
                    if(state == Qt::Unchecked)
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));
                    else
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                    cbIt->blockSignals(false);
                }
            });
    connect(ui->cb_userIO_all,&QCheckBox::stateChanged,this,[this](int state)
            {
                for(auto cbIt : m_reCheckBoxMap[Role::USER_STORE_IO])
                {
                    if(cbIt == ui->cb_userCheck_all || cbIt == ui->cb_userIO_allIn || cbIt == ui->cb_userIO_allOut)
                            continue;

                        cbIt->blockSignals(true);
                        if(state == Qt::Unchecked)
                            cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));
                        else
                            cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                        cbIt->blockSignals(false);
                }
            });

    QList<QCheckBox*> tmpCBS;
    tmpCBS.append(ui->cb_userIO_addIn);
    tmpCBS.append(ui->cb_userIO_deleteIn);
    tmpCBS.append(ui->cb_userIO_updateIn);
    tmpCBS.append(ui->cb_userIO_showIn);
    tmpCBS.append(ui->cb_userIO_findIn);
    connect(ui->cb_userIO_allIn,&QCheckBox::stateChanged,this,[tmpCBS](int state)
            {
                for(auto cbInIt : tmpCBS)
                {
                    cbInIt->blockSignals(true);
                    if(state == Qt::Unchecked)
                        cbInIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));
                    else
                        cbInIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                    cbInIt->blockSignals(true);
                }
            });
    tmpCBS.clear();
    tmpCBS.append(ui->cb_userIO_addOut);
    tmpCBS.append(ui->cb_userIO_deleteOut);
    tmpCBS.append(ui->cb_userIO_updateOut);
    tmpCBS.append(ui->cb_userIO_showOut);
    tmpCBS.append(ui->cb_userIO_findOut);
    connect(ui->cb_userIO_allOut,&QCheckBox::stateChanged,this,[tmpCBS](int state)
            {
                for(auto cbInIt : tmpCBS)
                {
                    cbInIt->blockSignals(true);
                    if(state == Qt::Unchecked)
                        cbInIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));

                    else
                        cbInIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                    cbInIt->blockSignals(true);
                }
            });

    connect(ui->cb_userCheck_all,&QCheckBox::stateChanged,this,[this](int state)
            {
                for(auto cbIt : m_reCheckBoxMap[Role::USER_STORE_CHECK])
                {
                    if(cbIt == ui->cb_userCheck_all)
                        continue;
                    cbIt->blockSignals(true);
                    if(state == Qt::Unchecked)
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Unchecked));
                    else
                        cbIt->setCheckState(static_cast<Qt::CheckState>(Qt::Checked));
                    cbIt->blockSignals(false);
                }
            });


    for(auto roleIt = m_checkBoxMap.begin();roleIt!=m_checkBoxMap.end();++roleIt)
    {
        for(auto cbIt = roleIt.value().begin();cbIt!=roleIt.value().end();++cbIt)
        {
            connect(cbIt.key(),&QCheckBox::stateChanged,this,[this, role = roleIt.key(),mask = cbIt.value()](int state)
            {
                if(state == Qt::Checked)
                {
                    m_currentPBits |= static_cast<uint16_t>(mask);
                }
                else if(state == Qt::Unchecked)
                    m_currentPBits &= ~static_cast<uint16_t>(mask);

                PermissionBitsChoseMenu::checkBoxDispose();
                qDebug() << "触发了选择框的信号";
            });
        }
    }
}

void PermissionBitsChoseMenu::initCheckBox()
{
    for(auto cbIt = m_reCheckBoxMap[m_currentRole].begin(); cbIt != m_reCheckBoxMap[m_currentRole].end(); ++cbIt)
    {
        if((static_cast<PB_t>(cbIt.key()) & m_currentPBits) == static_cast<PB_t>(cbIt.key()))
        {
            cbIt.value()->blockSignals(true);
            cbIt.value()->setCheckState(Qt::Checked);
            cbIt.value()->blockSignals(false);
        }
        else if((static_cast<PB_t>(cbIt.key()) & m_currentPBits) != 0)
        {
            cbIt.value()->blockSignals(true);
            cbIt.value()->setCheckState(Qt::PartiallyChecked);
            cbIt.value()->blockSignals(false);
        }
        else
        {
            cbIt.value()->blockSignals(true);
            cbIt.value()->setCheckState(Qt::Unchecked);
            cbIt.value()->blockSignals(false);
        }
    }
}


void PermissionBitsChoseMenu::checkBoxDispose()
{
    m_bitsCount = 0;

    if(m_currentRole == Role::USER_STORE_IO)
    {
        int inBitCount = 0, outBitCount = 0;
        for(auto cbIt = m_checkBoxMap[Role::USER_STORE_IO].begin(); cbIt != m_checkBoxMap[Role::USER_STORE_IO].end(); ++cbIt)
        {
            if(cbIt.key() == ui->cb_userIO_all || cbIt.key() == ui->cb_userIO_allIn || cbIt.key() == ui->cb_userIO_allOut )
            {
                continue;
            }
            else
            {
                if(cbIt.key()->checkState()==Qt::Checked && (static_cast<PB_t>(cbIt.value()) & static_cast<PB_t>(UPBits::USER_SIO_IN_ALL)))
                {
                    inBitCount++;
                    m_bitsCount++;
                }
                else if(cbIt.key()->checkState()==Qt::Checked && (static_cast<PB_t>(cbIt.value()) & static_cast<PB_t>(UPBits::USER_SIO_OUT_ALL)))
                {
                    outBitCount++;
                    m_bitsCount++;
                }
                else if(cbIt.key()->checkState()==Qt::Checked)
                {
                    m_bitsCount++;
                }
            }
        }

        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_ALL]->blockSignals(true);
        if(m_bitsCount >= m_checkBoxMap[Role::USER_STORE_IO].size() - 3)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_ALL]->setCheckState(Qt::Checked);
        else if(m_bitsCount == 0)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_ALL]->setCheckState(Qt::Unchecked);
        else
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_ALL]->setCheckState(Qt::PartiallyChecked);
        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_ALL]->blockSignals(false);

        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_IN_ALL]->blockSignals(true);
        if(inBitCount >= 5)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_IN_ALL]->setCheckState(Qt::Checked);
        else if(inBitCount == 0)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_IN_ALL]->setCheckState(Qt::Unchecked);
        else
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_IN_ALL]->setCheckState(Qt::PartiallyChecked);
        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_IN_ALL]->blockSignals(false);

        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_OUT_ALL]->blockSignals(true);
        if(outBitCount >= 5)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_OUT_ALL]->setCheckState(Qt::Checked);
        else if(outBitCount == 0)
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_OUT_ALL]->setCheckState(Qt::Unchecked);
        else
            m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_OUT_ALL]->setCheckState(Qt::PartiallyChecked);
        m_reCheckBoxMap[Role::USER_STORE_IO][UPBits::USER_SIO_OUT_ALL]->blockSignals(false);
    }
    else
    {
        for(auto cbIt = m_checkBoxMap[m_currentRole].begin(); cbIt != m_checkBoxMap[m_currentRole].end(); ++cbIt)
        {
            if(cbIt.key() == ui->cb_user_all || cbIt.key() == ui->cb_userInfo_all || cbIt.key() == ui->cb_userCheck_all)
            {
                continue;
            }
            else if(cbIt.key()->checkState() == Qt::Checked)
            {
                m_bitsCount++;
            }
        }

        switch(m_currentRole)
        {
        case Role::ADMIN:
        {
            m_reCheckBoxMap[m_currentRole][UPBits::USER_ADMIN_ALL]->blockSignals(true);
            if(m_bitsCount >= m_checkBoxMap[m_currentRole].size() - 1)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_ADMIN_ALL]->setCheckState(Qt::Checked);
            else if(m_bitsCount == 0)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_ADMIN_ALL]->setCheckState(Qt::Unchecked);
            else
                m_reCheckBoxMap[m_currentRole][UPBits::USER_ADMIN_ALL]->setCheckState(Qt::PartiallyChecked);
            m_reCheckBoxMap[m_currentRole][UPBits::USER_ADMIN_ALL]->blockSignals(false);
            break;
        }
        case Role::USER_INFO:
        {
            m_reCheckBoxMap[m_currentRole][UPBits::USER_INFO_ALL]->blockSignals(true);
            if(m_bitsCount >= m_checkBoxMap[m_currentRole].size() - 1)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_INFO_ALL]->setCheckState(Qt::Checked);
            else if(m_bitsCount == 0)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_INFO_ALL]->setCheckState(Qt::Unchecked);
            else
                m_reCheckBoxMap[m_currentRole][UPBits::USER_INFO_ALL]->setCheckState(Qt::PartiallyChecked);
            m_reCheckBoxMap[m_currentRole][UPBits::USER_INFO_ALL]->blockSignals(false);
            break;
        }
        case Role::USER_STORE_CHECK:
        {
            m_reCheckBoxMap[m_currentRole][UPBits::USER_SCK_ALL]->blockSignals(true);
            if(m_bitsCount >= m_checkBoxMap[m_currentRole].size() - 1)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_SCK_ALL]->setCheckState(Qt::Checked);
            else if(m_bitsCount == 0)
                m_reCheckBoxMap[m_currentRole][UPBits::USER_SCK_ALL]->setCheckState(Qt::Unchecked);
            else
                m_reCheckBoxMap[m_currentRole][UPBits::USER_SCK_ALL]->setCheckState(Qt::PartiallyChecked);
            m_reCheckBoxMap[m_currentRole][UPBits::USER_SCK_ALL]->blockSignals(false);
            break;
        }

        default:break;
        }
    }
}

